<?php

declare(strict_types=1);

namespace App\Service;

use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use App\Library\Common;
use App\Model\FlyCart;
use App\Model\Moment;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use phpDocumentor\Reflection\Types\Integer;

/**
 * 购物车
 * Class FlyCartService
 * @package App\Service
 */
class FlyCartService extends BaseService
{

    const CART_STYLE_SHOP = 1; // 商城购物车
    const CART_STYLE_ORDER = 2; // 点餐购物车

    /**
     * @Inject
     * @var FlyShopService
     */
    private $shop;

    /**
     * @Inject
     * @var SkuService
     */
    private $sku;

    /**
     * 保存购物车
     * @param array $data
     * @param int $cart_style 购物车
     * @return bool|array
     */
    public function cartAdd(array $data, $cart_style = self::CART_STYLE_SHOP)
    {
        Db::beginTransaction();
        $this_food_id = 0;
        $fails_p = [];// sku_id product_id sku_name product_name
        // 达人圈验证
        $moments_id = empty($data['moments_id']) ? 0 : (int)$data['moments_id'];
        foreach ($data['carts'] as $params) {
            if (!empty($params['id'])) {
                $cart_instance = $this->getModelInstance()->where(['user_id' => $data['user_id']])->find($params['id']);
                // 无法修改 不存在
                if (empty($cart_instance)) {
                    Db::rollBack();
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '购物车不存在');
                }
                $cart_instance->update_time = time();
            } else {
                // 对于商品列表再次添加购物车，如果存在增加其数量
                $sku_tmp = $this->getModelInstance()->where(['user_id' => $data['user_id'], 'sku_id' => $params['sku_id']])->select(['id', 'quantity'])->first();
                if (!empty($sku_tmp) && !empty($sku_tmp->toArray())) {
                    $params['quantity'] = $params['quantity'] + $sku_tmp->quantity;
                    $params['id'] = $sku_tmp->id;
                    $cart_instance = $this->getModelInstance()->find($sku_tmp->id);
                    $cart_instance->update_time = time();
                } else {
                    $cart_instance = $this->getModelInstance();
                    $cart_instance->create_time = time();
                }
            }

            $skus = $this->sku->get_sku_by_id([$params['sku_id']]);
            // 商品不存在
            if (empty($skus)) {
                Db::rollBack();
                throw new BusinessException(ErrorCode::NORMAL_ERROR, '所选商品不存在');
            }
            $sku = $skus[0];
            if (empty($sku['with_product'])) {
                throw new BusinessException(ErrorCode::NORMAL_ERROR, '商品无效');
            }
            // 购物车结算方式（点餐按店铺生成订单）（商城不区分店铺生成订单）todo
            $params['cart_style'] = $sku['with_product']['category_id'] > 0 ? self::CART_STYLE_ORDER : self::CART_STYLE_SHOP;
            // 美食餐品不需要判断行业
            if ($params['cart_style'] == self::CART_STYLE_SHOP) {
                if (empty($sku['with_product']['industry_info'])) {
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '未获取对应行业');
                } else {
                    if ($sku['with_product']['industry_info']['is_unreal'] == 1) {
                        throw new BusinessException(ErrorCode::NORMAL_ERROR, '虚拟产品不支持购物车结算');
                    }
                }
            }

            if (empty($sku['with_product'] || empty($sku['with_product']['shop_id']))
                || $sku['with_product']['is_illegal'] == 1// 非法
                || $sku['with_product']['is_show'] != 1 // 不展示
                || $sku['with_product']['check_status'] != 1) { // 1未审核
                Db::rollBack();
                // 服务类订单失效时返回错误信息
                if ($cart_style == self::CART_STYLE_ORDER) {
                    $fails_p[] = [
                        'sku_id' => $sku['sku_id'] ?? 0,
                        'product_id' => $sku['with_product']['id'],
                        'sku_name' => $sku['sku_name'] ?? "",
                        'product_name' => $sku['with_product']['product_name']
                    ];
                    $cart_instance = null;
                    continue;
                } else {
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '商品无效');
                }
            }
            // 判断是否为达人分销商品
            if (!empty($data['moments_id'])) {
                // 为分销下单-为分销成功用户提成
                $moment_info = make(Moment::class)
                    ->where(['id' => $moments_id])
                    ->whereHas('with_valid_dr', function ($where) use ($sku) {
                        $where->where('product_id', $sku['product_id']);
                    })->first();
                // 动态存在 -> 推广中 -
                if (!empty($moment_info) && !empty($moment_info->with_valid_dr) && !empty($moment_info->with_valid_dr->with_shop_ad)) {
                    $params['moments_id'] = $moments_id;
                }
            }

            $params['shop_id'] = $sku['with_product']['shop_id'];
            $params['product_id'] = $sku['product_id'];
            $cast = ['product_id', 'user_id', 'sku_id', 'shop_id', 'cart_style', 'quantity', 'is_selected'];
            foreach ($params as $k => $v) {
                if (in_array($k, $cast)) {
                    $cart_instance->$k = $v;
                }
            }
            $cart_instance->user_id = $data['user_id'];
            if (!$cart_instance->save()) {
                Db::rollBack();
                return 0;
            }
            if ($params['cart_style'] == self::CART_STYLE_ORDER) {
                $this_food_id = $cart_instance->id;
            }
            $cart_instance = null;
        }
        Db::commit();
        return $cart_style == self::CART_STYLE_ORDER ? (count($data['carts']) == 1 ? $this_food_id : $fails_p) : true;
    }

    /**
     * 获取购物车列表
     * @param int $user_id
     * @param int $cart_style 购物车类型：1商品 2点餐
     * @param int $shop_id 美食店铺ID
     * @return array
     */
    public function getCartSku(int $user_id, $cart_style = self::CART_STYLE_SHOP, $shop_id = 0): array
    {
        $cart_style = $cart_style == self::CART_STYLE_SHOP ? self::CART_STYLE_SHOP : self::CART_STYLE_ORDER;
        $instance = $this->getModelInstance()
            ->where(['user_id' => $user_id, 'cart_style' => $cart_style])
            ->get();
        if (empty($instance)) {
            return [];
        }
        $instance_arr = $instance->toArray();
        $data = $this->showByShop($instance_arr);
        $total_price = 0;
        $total_quantity = 0;
        $order_shop = [];
        foreach ($data as $shop) {
//            if ($cart_style == self::CART_STYLE_ORDER) {
            if (!empty($shop_id)) {
                if ($shop['id'] == $shop_id) {
                    foreach ($shop['carts'] as $cart) {
                        if (1 == $cart['is_selected'] && 1 == $cart['is_valid']) {
                            $total_price += Common::yuan2fen(floatval($cart['sku_info']['step_price'])) * $cart['quantity'];
                            $total_quantity += $cart['quantity'];
                        }
                    }
                    // 购物车获取当前店铺点餐列表
                    $order_shop = $shop;
                }
            } else {
                foreach ($shop['carts'] as $cart) {
                    if (1 == $cart['is_selected'] && 1 == $cart['is_valid']) {
                        $total_price += Common::yuan2fen(floatval($cart['sku_info']['step_price'])) * $cart['quantity'];
                        $total_quantity += $cart['quantity'];
                    }
                }
            }
        }
        $total_price = Common::fen2yuan($total_price);
        return [
            'total_price' => $total_price,
            'total_quantity' => $total_quantity,
            'data' => !empty($shop_id) ? $order_shop : $data// 根据店铺返回对应购物车信息
        ];
    }

    /**
     * 获取购物车列表
     * @param int $user_id
     * @param int $cart_style
     * @return int
     */
    public function countSkuCate(int $user_id, $cart_style = self::CART_STYLE_SHOP)
    {
        $cart_style = $cart_style == self::CART_STYLE_SHOP ? self::CART_STYLE_SHOP : self::CART_STYLE_ORDER;
        return FlyCart::query()->where(['user_id' => $user_id, 'cart_style' => $cart_style])->count();
    }

    /**
     * 根据店铺展示
     * @param array $instance_arr
     * @param bool $from_cart 从购物车结算:
     * @return array
     */
    public function showByShop(array $instance_arr, $from_cart = true): array
    {

        if (empty($instance_arr)) {
            return [];
        }
        // 获取购物车店铺信息
        $tmpCart = [];

        foreach ($instance_arr as $k => &$value) {
            $sku_info = $this->sku->get_sku_by_id([$value['sku_id']], true);
            if (empty($sku_info)) {
                unset($instance_arr[$k]);
                continue;
            }
            if (!empty($sku_info) && !empty($sku_info['with_product'])
                && $sku_info['with_product']['is_illegal'] == 0
                && $sku_info['with_product']['check_status'] == 1
                && $sku_info['with_product']['is_show'] == 1) {
                $value['is_valid'] = 1;// 有效
            } else {
                $value['is_valid'] = 0;
            }

            if (!empty($sku_info['with_product']) && !empty($sku_info['with_product']['landmark_info'])) {
                $value['landmark'] = $sku_info['with_product']['landmark_info']['name'];
            } else {
                $value['landmark'] = "";
            }

            $value['sku_info'] = $sku_info;
            $value['min_quantity'] = 0;
            // 阶梯价默认为sku默认价
            $value['sku_info']['step_price'] = $value['sku_info']['single_price'];
            // 匹配阶梯价
            foreach ($sku_info['step_price'] as $price) {
                if (empty($value['min_quantity'])) {
                    // 下单数量超过阶梯数量：选择阶梯价格-记录阶梯数量
                    if ($value['quantity'] >= $price['num']) {
                        $value['min_quantity'] = $price['num'];
                        $value['sku_info']['step_price'] = $price['single_price'];
                    }
                } else {
                    // 更高的阶梯数量：更高的阶梯价格-记录更高的阶梯数量
                    if ($value['min_quantity'] < $price['num'] && $value['quantity'] >= $price['num']) {
                        $value['min_quantity'] = $price['num'];
                        $value['sku_info']['step_price'] = $price['single_price'];
                    }
                }
            }
        }
        // 获取店铺信息
        if (empty(array_column($instance_arr, 'shop_id'))) {
            $shop_ids = [];
            foreach ($instance_arr as $item) {
                if (empty($item) || empty($item['sku_info']) || empty($item['sku_info']['with_product'])) {
                    return [];
                }
                $shop_ids[] = $item['sku_info']['with_product']['shop_id'];
            }
            $shop_info = $this->shop->getShopById($shop_ids);
        } else {
            $shop_info = $this->shop->getShopById(array_column($instance_arr, 'shop_id'));
        }
        foreach ($shop_info as $sv) {
            $tmp = [
                'id' => $sv['id'],
                'shop_name' => $sv['shop_name'],
                'shop_phone' => $sv['phone'],
                'carts' => []
            ];
            foreach ($instance_arr as $k => $item2) {
                // 从购物车结算
                if ($from_cart) {
                    if ($item2['shop_id'] == $sv['id'] && !in_array($item2['sku_id'], array_column($tmp['carts'], 'sku_id'))) {
                        $tmp['carts'][] = $item2;
                    }
                } else {
                    // 非购物车结算
                    if (isset($item2['sku_info']['with_product']['shop_id']) && $item2['sku_info']['with_product']['shop_id'] == $sv['id']
                        && !in_array($item2['sku_id'], array_column($tmp['carts'], 'sku_id'))) {
                        $tmp['carts'][] = $item2;
                    }
                }
            }
            $tmpCart[] = $tmp;
        }
        return $tmpCart;
    }


    /**
     * 删除购物车商品
     * @param int $user_id
     * @param array $cart_id
     * @param int $clear 是否删除全部购物车商品 0:否 1是 2下单后清除(清除选中的)
     * @param int $cart_style
     * @return bool
     */
    public function delCart(int $user_id, array $cart_id, int $clear = 0, $cart_style = self::CART_STYLE_SHOP): bool
    {
        $cart_style = $cart_style == self::CART_STYLE_SHOP ? self::CART_STYLE_SHOP : self::CART_STYLE_ORDER;
        // 清空购物车
        if (empty($user_id) || (empty($cart_id) && $clear == 0)) {
            return false;
        }
        if ($clear == 1) {
            $this->getModelInstance()->where(['user_id' => $user_id, 'cart_style' => $cart_style])->delete();
        } elseif ($clear == 2) {
            $this->getModelInstance()->where(['user_id' => $user_id, 'is_selected' => 1, 'cart_style' => $cart_style])->delete();
        }
        $this->getModelInstance()->where(['user_id' => $user_id, 'cart_style' => $cart_style])->whereIn('id', $cart_id)->delete();
        return true;
    }

    /**
     * 获取购物车数量
     * @param int $user_id
     * @param int $cart_style
     * @return int
     */
    public function getCartNum(int $user_id, $cart_style = self::CART_STYLE_SHOP): int
    {
        $cart_style = $cart_style == self::CART_STYLE_SHOP ? self::CART_STYLE_SHOP : self::CART_STYLE_ORDER;
        return $this->getModelInstance()
            ->where(['user_id' => $user_id, 'cart_style' => $cart_style])
            ->count();
    }
}